/*
 * Copyright (C) 2014 Sony Computer Entertainment Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "SigreTexture.h"

#if USE(ACCELERATED_COMPOSITING) && USE(ACAGI)

#include <stdio.h>
#define DBG_TRACE printf("%s %d\n", __PRETTY_FUNCTION__, __LINE__)

namespace WebCore {

PassRefPtr<SigreTexture> SigreTexture::create(Allocator* allocator, IntSize textureSize)
{
    SigreTexture* texture = new SigreTexture(allocator, textureSize);
    return adoptRef(texture);
}

PassRefPtr<SigreTexture> SigreTexture::duplicate(PassRefPtr<SigreTexture> original)
{
    SigreTexture* texture = new SigreTexture(original->m_allocator, original->textureSize());
    if (texture && texture->isValid() && original->isValid())
        memcpy(texture->m_texture.buffer, original->m_texture.buffer, texture->m_texture.stride * texture->m_texture.height);
    return adoptRef(texture);
}

SigreTexture::SigreTexture(Allocator* allocator, IntSize textureSize)
    : m_allocator(allocator)
{
    ASSERT(m_allocator);
    m_texture = m_allocator->allocateTexture(tilebackend::IntSize(textureSize.width(), textureSize.height()), tilebackend::kARGB32);
}

SigreTexture::~SigreTexture()
{
    m_allocator->freeTexture(m_texture);
}

void SigreTexture::updateContents(const void* srcData, const IntRect& targetRect, const IntPoint& sourceOffset, int bytesPerLine)
{
    IntRect dstRect(IntPoint(), textureSize());
    dstRect.intersect(targetRect);

    uint8_t* dst = (uint8_t*)m_texture.buffer;
    uint8_t* src = (uint8_t*)srcData;

    if (!dstRect.x() && !sourceOffset.x() && dstRect.width() == m_texture.width && bytesPerLine == m_texture.stride) {
        dst += dstRect.y() * m_texture.stride;
        src += sourceOffset.y() * bytesPerLine;
        size_t copySize = dstRect.height() * bytesPerLine;
        memcpy(dst, src, copySize);
        return;
    }

    const int bpp = 4;
    dst += dstRect.x() * bpp + dstRect.y() * m_texture.stride;
    src += sourceOffset.x() * bpp + sourceOffset.y() * bytesPerLine;
    size_t copySize = dstRect.width() * bpp;
    for (int y = 0; y < dstRect.height(); y++) {
        memcpy(dst, src, copySize);
        dst += m_texture.stride;
        src += bytesPerLine;
    }
}

}
#endif
